#ifndef MY_INC_PHY_PHY_Filter_H_
#define MY_INC_PHY_PHY_Filter_H_

#include <MY_INC\PHY\PHY_IIRFilter.h>
#include <stdint.h>
#include <stdio.h>

#define Filtering_Order    8                      // 滤波器阶数
#define Filter_Window_Size (1 << Filtering_Order) // 滤波器窗口大小, 2^Filtering_Order
/**
 * @brief 移位滤波器结构体，用于uint16_t类型的ADC值滤波
 */
typedef struct
{
    uint16_t buffer[Filter_Window_Size]; // 存储历史数据的缓冲区
    uint8_t  index;                      // 当前写入位置的索引
    uint32_t sum;                        // 数据值的总和
} Filter_Uint16_t_Typedef;

/**
 * @brief 移位滤波器函数，用于对uint16_t类型的ADC值进行滑动平均滤波
 * @param Record 存储滤波器状态的结构体指针
 * @param New_Value 新的ADC值
 * @param Return_Value 滤波后的ADC值
 */
static inline void Filter_Shift_Uint16_t_Inline(Filter_Uint16_t_Typedef *Record, uint16_t New_Value,
                                                uint32_t *Return_Value)
{
    Record->sum += New_Value - Record->buffer[Record->index];
    Record->buffer[Record->index] = New_Value;
    Record->index = (Record->index + 1) % Filter_Window_Size;
    *Return_Value = (uint32_t)(Record->sum >> Filtering_Order);
}
/**********滑动平均滤波器*****************/
/**
 * @brief 滑动平均滤波器结构体
 */
// typedef struct
//{
//     float Multiplier; // 滤波器系数
//     float Yn_1;       // 输出信号Yn-1
// } FilterMovAvg_Typedef;
// void                Filter_MovAvg_Init(FilterMovAvg_Typedef *Record, float Freq, float ts);
// static inline float Filter_MovAvg_Inline(FilterMovAvg_Typedef *Record, float Xn)
//{
//     float Yn = Record->Multiplier * (Xn - Record->Yn_1) + Record->Yn_1; // 滤波器输出
//     Record->Yn_1 = Yn;                                                  // 更新 Yn-1
//     return Yn;                                                          // 返回当前输出信号
// }

typedef struct
{
    uint32_t Yn;
} FilterMovAvg_Typedef;
void                   Filter_MovAvg_Init(FilterMovAvg_Typedef *Record, float Freq, float ts);
static inline uint32_t Filter_MovAvg_Inline(FilterMovAvg_Typedef *Record, uint32_t Xn, const uint32_t filterorder)
{
    Record->Yn += (Xn - Record->Yn) >> filterorder; // 滤波器输出
    return Record->Yn;                              // 返回当前输出信号
}
//_state_var: 滤波器接收数据的持久变量
//_input_val: 需要滤波的输入值
//_shift_amount: 滤波器的移位量，通常为滤波器，为2的n次方，n为滤波器阶数
#define FILTER_MOVAVG(_state_var, _input_val, _shift_amount) \
    ((_state_var) += (((uint32_t)_input_val) - (uint32_t)(_state_var)) >> (_shift_amount))

/**********低通滤波器*****************/
/**
 * @brief 低通滤波器结构体
 */
typedef struct
{
    float Coeff_B0;
    float Coeff_A1;

    float Xn_1; // 输入信号Xn-1
    float Yn_1; // 输出信号Yn-1
} FilterLow_Typedef;

/**
 * @brief 初始化低通滤波器
 * @param Record 存储滤波器状态的结构体指针
 * @param f 目标截止频率，单位Hz
 * @param ts 执行周期，单位秒
 */
void Filter_Low_Init(FilterLow_Typedef *Record, float f, float ts);

/**
 * @brief 执行低通滤波
 * @param Record 存储滤波器状态的结构体指针
 * @param x_n 指向输入值的指针
 */
static inline float Low_Filtering_Inline(FilterLow_Typedef *Record, float Xn)
{
    float Yn = Record->Coeff_B0 * (Xn + Record->Xn_1) - (Record->Coeff_A1 * Record->Yn_1);
    Record->Xn_1 = Xn; // Xn-1 = Xn
    Record->Yn_1 = Yn; // Yn-1 = Yn
    return Yn;         // 返回当前输出信号
}

/**
 * @brief 梯形滤波器结构体
 */
typedef struct
{
    Coeff_2P2Z notch;
} FilterTrap_Typedef;

/**
 * @brief 初始化梯形滤波器
 * @param Record 存储滤波器状态的结构体指针
 * @param wo 角频率，单位rad/s
 * @param ws 阻尼系数
 * @param ts 执行周期，单位秒
 */
void Filter_Trap_Init(FilterTrap_Typedef *filterTrap, float ts, float wn, float c2, float c1);
void Filter_Trap_Reset(FilterTrap_Typedef *filterTrap);
/**
 * @brief 执行梯形滤波
 * @param Record 存储滤波器状态的结构体指针
 * @param In 需要滤波的输入值
 * @return 滤波后的输出值
 */
static inline float Trap_Filter_Inline(FilterTrap_Typedef *Record, float In)
{
    return Diff2P2Z_Filter_Inline(&Record->notch, In);
}
#endif /* MY_INC_Filter_H_ */
